#include<bits/stdc++.h>
using namespace std;
#define int long long

struct node {
	int x, y, step;
};

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};

int n, m;
bool vis[305][305];
char ch[305][305];

vector<int> trans['Z' + 5];
bool last_trans['Z' + 5][90005];	// 再次传送时的时间不能与之前相同

int qx, qy;

node transfer(node t) {
	// 判断传送装置
	char lt = ch[t.x][t.y];
	int x1 = trans[lt][0];
	int y1 = trans[lt][1];
	int x2 = trans[lt][2];
	int y2 = trans[lt][3];

	if (x1 == t.x && y1 == t.y) {
		return {x2, y2, t.step};
	} else {
		return {x1, y1, t.step};
	}
}

int ans = INT_MAX;

void bfs() {
	queue<node> q;
	q.push({qx, qy, 0});
	vis[qx][qy] = 1;

	while (!q.empty()) {
		node t = q.front();
		q.pop();

//		cout << "(" << t.x << ", " << t.y << ")" << "->" << ch[t.x][t.y] << endl;

		if (ch[t.x][t.y] == '=') {
//			ans = min(ans, t.step);
//			continue;
			cout << t.step;
			return ;
		}

//		for (int i = 3; i >= 0; i--) {
		for (int i = 0; i < 4; i++) {
			int xx = t.x + dx[i];
			int yy = t.y + dy[i];

			if (xx < 1 || xx > n || yy < 1 || yy > m || vis[xx][yy] || ch[xx][yy] == '#')
				continue;

			node waiting_push = {xx, yy, t.step + 1};

			if (!trans[ch[xx][yy]].empty()) { // && !last_trans[ch[xx][yy]][waiting_push.step]) {
				q.push(transfer(waiting_push));
//				last_trans[ch[xx][yy]][waiting_push.step] = 1;
			} else {
				q.push(waiting_push);
				vis[xx][yy] = 1;
			}
		}
	}
}

signed main() {
//	freopen("D:\\code\\OJ code\\LuoGu\\P1825_2.in", "r", stdin);
	freopen("D:\\code\\OJ code\\LuoGu\\P1825_5.in", "r", stdin);
//	freopen("D:\\code\\OJ code\\LuoGu\\P1825_15.in", "r", stdin);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			cin >> ch[i][j];
			if (ch[i][j] == '@')
				qx = i, qy = j;
			if ('A' <= ch[i][j] && ch[i][j] <= 'Z') {
				trans[ch[i][j]].push_back(i);
				trans[ch[i][j]].push_back(j);
			}
		}
	}

	bfs();
//	cout << ans;
	return 0;
}
